/*
 * File     : StringPool.java
 * Created  : 22 Apr 2011
 *
 * Copyright © 2011 Matthew Wilson (mj. {my-surname} .uk {at} gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.dni.type;


/**
 * <p>
 *  Encapsulates a cached pool of native strings.
 * </p>
 * <p>
 *  A variable-sized memory pool is used to hold native strings.  A mapping is
 *  held so that a native string for a Java string can be looked up in constant
 *  time.
 * </p>
 * <p>
 *  The size of the pool is dynamic, and can grow up to some maximum limit.
 *  When a new string is requested, more memory will be allocated as required.
 *  If insufficient memory is available, a temporary (uncached) string will
 *  created.</p>
 * </p>
 * <p>
 *  When no longer required, the whole pool can be {@linkplain #free() freed},
 *  freeing all strings in it; all native strings will then become invalid.
 *  Individual strings can be {@linkplain #drop(String) dropped} when no longer
 *  required, freeing the memory when possible.
 * </p>
 * <p>
 *  Because the lifetime of the native string requires explicit management, and
 *  the nature of this class is quite dynamic, the user must request a string
 *  with {@link #get(String)} and then release it with
 *  {@link #release(NativeString)} when no longer required.  This gives the
 *  guarantee that a string that is in use will not be freed.
 * </p>
 *
 * @author Matthew Wilson
 */
public interface StringPool extends Freeable
{

    /**
     * <p>
     *  Looks up a string in the cache.
     * </p>
     * <p>
     *  If the string is not present, it is converted to a native string, and
     *  that string possibly cached for later.
     * </p>
     * <p>
     *  The returned native string must be
     *  {@linkplain #release(NativeString) released} when no longer required.
     * </p>
     *
     * @param string
     *            the string
     *
     * @return a native string
     */
    NativeString get( String string );

    /**
     * <p>
     *  Releases a string that was obtained from {@link #get(String)}.
     * </p>
     *
     * @param string
     *            the native string
     */
    void release( NativeString string );

    /**
     * <p>
     *  Indicates to the pool that the given string is no longer needed in the
     *  cache.
     * </p>
     * <p>
     *  At some future point, when the string is no longer in use, the native
     *  string's memory will be freed.
     * </p>
     *
     * @param string
     *            the native string
     */
    void drop( String string );


    /**
     * Implemented by types that expose the {@link StringPool} they use.
     *
     * @author Matthew Wilson
     */
    public interface StringPoolOwner
    {

        /**
         * Obtains the owned string pool.
         *
         * @return the string pool
         */
        StringPool getStringPool();

    }

}
